#ifndef _MONSTER_H_
#define _MONSTER_H_

#include <string>

#include "INamable.h"
#include "IRepresentable.h"
#include "IMovable.h"
#include "ILiving.h"

/**
 * Defines a monster.
 *
 * This is the monster class. To define this class, proper objects must be supplied to it,
 * that will define the monster behaviour.
 */
class Monster 
{
private:
  /**
   * Holder for name.
   */
  INamable* name;

  /**
   * Holder for representation.
   */
  IRepresentable* representation;

  /**
   * Holder for object position.
   */
  IMovable* move;

  /**
   * Holder for objects life.
   */
  ILiving* life;

public:
  /**
   * Basic constructor. Just provide appropiate objects to define
   * the monster behaviour.
   *
   * @arg[in] n : Will define the monster's name
   * @arg[in] r : Will define monster's representation
   * @arg[in] m : Will define monster's position
   * @arg[in] l : Will define monster's livibility
   */
  Monster(INamable* n, IRepresentable* r, IMovable* m,
             ILiving* l) : name(n), representation(r), move(m), life(l) {}

  /**
   * Returns the monster's name.
   *
   * @return The monster's name.
   */
  const std::string& getName() const { return name->getName(); }

  /**
   * Gets the ASCII representation of the monster.
   *
   * @return The ASCII representation of the monster.
   */
  char getAsciiRepresentation() const { return representation->getAsciiRepresentation(); }

  /**
   * Gets the monster's health.
   *
   * @return The monster's health.
   */
  int getHealth() const { return life->getHealth(); }

  /**
   * Hurts the monster by a given amount.
   *
   * @arg[in] h : Damage that will be dealt to monster.
   */
  void hurt(int h) { life->hurt(h); }

  /**
   * Heals the monster by a given amount.
   *
   * @arg[in] h : Heals the monster by a given amount.
   */
  void heal(int h) { life->heal(h); }

  /**
   * Gets the position of the monster.
   *
   * @return The position of the monster 
   */
  const IMovable::movableVector& getPosition() const { return move->getPosition(); }

  /**
   * Sets the position of the monster.
   *
   * @arg[in] v : The position of the monster to be set
   */
  void setPosition(const IMovable::movableVector& v) { move->setPosition(v); }

  /**
   * Moves the monster by a given vector.
   *
   * @arg[in] v : Vector that will move the monster 
   */
  void movePosition(const IMovable::movableVector& v) { move->movePosition(v); }
  
};
#endif /* _MONSTER_H */

